/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package beans.validation;

import beans.util.GeonameWS;
import db.entities.Medic;
import db.entities.Patient;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import logger.Log;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;
import utility.Hash;

/**
 *
 * @author marcy
 */
public class ConvalidaPaziente implements Serializable {
    //Gestione delle connessioni al db

    EntityManagerFactory emf;
    EntityManager em;
    //Parte dell'anagrafica
    private String nome;
    private String cognome;
    private String username;
    private String maschio;
    private String password;
    private Date data_nascita;
    private String luogo_nascita;
    private String indirizzo;
    private int cap;
    private float latitudine;
    private float longitudine;
    private String foto = "/resources/img/it.png";
    //Parte referenze
    private String cellulare;
    private String email;
    private int id_capovillaggio;
    private int madre;
    private int padre;
    private int medico;
    private int id_paziente;
    private File file;
    private int uplAvb = 1;
    private long timestamp;
    
    public void insertLatLng(){
        if(this.luogo_nascita != null){
            List<Float> coords = new GeonameWS().getCoordsContent(this.luogo_nascita);
            this.latitudine = coords.get(0);
            this.longitudine = coords.get(1);
        }
    }

    public void paint(OutputStream stream, Object object) throws IOException {
        if(file != null )
        stream.write(getBytesFromFile(this.file));
    }

    private static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        // Get the size of the file
        long length = file.length();

        if (length > Integer.MAX_VALUE) {
            // File is too large
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int) length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
                && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file " + file.getName());
        }

        // Close the input stream and return bytes
        is.close();
        return bytes;
    }

    public ConvalidaPaziente() {
        emf = Persistence.createEntityManagerFactory("PortaleVisitePU");
        em = emf.createEntityManager();
    }

    //Parte per gli autocomplete dei suggestion Box
    public List<Patient> autocompleteMadre(Object event) {
        String pref = (event != null) ? event.toString() : "";
        List<Patient> list = em.createNativeQuery("Select * From Patient e "
                + "where e.nome like '" + pref + "%' or e.cognome like '" + pref + "%' and e.maschio='1' limit 0, 10", Patient.class).getResultList();
        if (list != null) {
            return list;
        } else {
            return new ArrayList<Patient>();
        }
    }

    public List<Patient> autocompletePadre(Object event) {
        String pref = (event != null) ? event.toString() : "";
        List<Patient> list = em.createNativeQuery("Select * From Patient e "
                + "where e.nome like '" + pref + "%' or e.cognome like '" + pref + "%' limit 0, 10", Patient.class).getResultList();
        if (list != null) {
            return list;
        } else {
            return new ArrayList<Patient>();
        }
    }

    public List<Patient> autocompleteCapovillaggio(Object event) {
        String pref = (event != null) ? event.toString() : "";
        List<Patient> list = em.createNativeQuery("Select * From Patient e "
                + "where e.nome like '" + pref + "%' or e.cognome like '" + pref + "%' limit 0, 10", Patient.class).getResultList();
        if (list != null) {
            return list;
        } else {
            return new ArrayList<Patient>();
        }
    }

    public List<Medic> autocompleteMedico(Object event) {
        String pref = (event != null) ? event.toString() : "";
        List<Medic> list = em.createNativeQuery("Select * From Medic m "
                + "where m.nome like '" + pref + "%' or m.cognome like '" + pref + "%' limit 0, 10", Medic.class).getResultList();
        if (list != null) {
            return list;
        } else {
            return new ArrayList<Medic>();
        }
    }
    //Fine suggestion box

    //Inizio fileUpload per foto paziente
    public void listener(UploadEvent event) throws Exception {
        //Ottengo il file temporaneo caricato
        UploadItem item = event.getUploadItem();

        //Ottengo la servlet context per avere accesso al metodo getRealPath
        FacesContext context = FacesContext.getCurrentInstance();
        HttpServletRequest origRequest = (HttpServletRequest) context.getExternalContext().getRequest();
        ServletContext servCtx = origRequest.getServletContext();

        //Calcolo la stringa hash della foto caricata in modo che sia univoca e non crei clash        
        String name = Hash.calcolaHash(item.getFile());
        name += "." + item.getContentType().substring(item.getContentType().length() - 3);

        //Salvo la foto sul Fs
        file = new File(servCtx.getRealPath("/resources/img/" + name));
        OutputStream out = new FileOutputStream(file);
        InputStream in = new FileInputStream(item.getFile());
        byte[] buffer = new byte[1024];
        int len;
        //Copio la foto dal file temporaneo a quello creato nel fs
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer);
        }
        //Chiudo i vari Stream
        in.close();
        out.close();

        //Aggiorno l'url della foto
        this.foto = "/resources/img/" + name;
        Log.getLogger().debug(this.foto);
        uplAvb--;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }    

    public int getMedico() {
        return medico;
    }

    public void setMedico(int medico) {
        this.medico = medico;
    }

    public String getLuogo_nascita() {
        return luogo_nascita;
    }

    public void setLuogo_nascita(String luogo_nascita) {
        this.luogo_nascita = luogo_nascita;
    }

    public int getCap() {
        return cap;
    }

    public void setCap(int cap) {
        this.cap = cap;
    }

    public String getCellulare() {
        return cellulare;
    }

    public void setCellulare(String cellulare) {
        this.cellulare = cellulare;
    }

    public String getCognome() {
        return cognome;
    }

    public void setCognome(String cognome) {
        this.cognome = cognome;
    }

    public Date getData_nascita() {
        return data_nascita;
    }

    public void setData_nascita(Date data_nascita) {
        this.data_nascita = data_nascita;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFoto() {
        return foto;
    }

    public void setFoto(String foto) {
        this.foto = foto;
    }

    public int getId_capovillaggio() {
        return id_capovillaggio;
    }

    public void setId_capovillaggio(int id_capovillaggio) {
        this.id_capovillaggio = id_capovillaggio;
    }

    public int getId_paziente() {
        return id_paziente;
    }

    public void setId_paziente(int id_paziente) {
        this.id_paziente = id_paziente;
    }

    public String getIndirizzo() {
        return indirizzo;
    }

    public void setIndirizzo(String indirizzo) {
        this.indirizzo = indirizzo;
    }

    public float getLatitudine() {
        return latitudine;
    }

    public void setLatitudine(float latitudine) {
        this.latitudine = latitudine;
    }

    public float getLongitudine() {
        return longitudine;
    }

    public void setLongitudine(float longitudine) {
        this.longitudine = longitudine;
    }

    public int getMadre() {
        return madre;
    }

    public void setMadre(int madre) {
        this.madre = madre;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public int getPadre() {
        return this.padre;
    }

    public void setPadre(int padre) {
        this.padre = padre;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getMaschio() {
        return maschio;
    }

    public void setMaschio(String maschio) {
        this.maschio = maschio;
    }

    public int getUplAvb() {
        return uplAvb;
    }

    public void setUplAvb(int uplAvb) {
        this.uplAvb = uplAvb;
    }
    
    public void clear(){
        setUplAvb(1);
    } 
    
    

    public String insertIntoDb() {
        //id per il paziente e per la referenza
        //
        //int id_referenza =(int)((Long)  em.createNativeQuery("Select max(r.id) From Referenze r").getSingleResult()).longValue();
        //id_referenza++;
        //inizio la transazione per l'aggiunta del paziente
        em.getTransaction().begin();
        em.createNativeQuery("INSERT INTO Patient ( nome, cognome, username, password, data_nascita, luogo_nascita, indirizzo, cap, longitudine, latitudine, foto, id_med, maschio ) "
                + "VALUES (  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) ").setParameter(1, nome).setParameter(2, cognome).setParameter(3, username).setParameter(4, password).setParameter(5, data_nascita).setParameter(6, luogo_nascita).setParameter(7, indirizzo).setParameter(8, cap).setParameter(9, longitudine).setParameter(10, latitudine).setParameter(11, foto).setParameter(12, medico).setParameter(13, maschio).executeUpdate();
        em.getTransaction().commit();
        em.getTransaction().begin();

        id_paziente = (int) ((Long) em.createNativeQuery("Select max(e.id) From Patient e").getSingleResult()).longValue();


        if (madre == 0 && padre == 0) {
            em.createNativeQuery("INSERT INTO Referenze ( cellulare, email, id_capovillaggio, id_medico, id_paz ) "
                    + "VALUES (?,?,?,?,?)").setParameter(1, cellulare).setParameter(2, email).setParameter(3, id_capovillaggio).setParameter(4, medico).setParameter(5, id_paziente).executeUpdate();
        } else if (madre == 0 && padre != 0) {
            em.createNativeQuery("INSERT INTO Referenze (  cellulare, email, id_capovillaggio, id_medico, id_paz, id_padre ) "
                    + "VALUES (?,?,?,?,?,?)").setParameter(1, cellulare).setParameter(2, email).setParameter(3, id_capovillaggio).setParameter(4, medico).setParameter(5, id_paziente).setParameter(6, padre).executeUpdate();
        } else if (padre == 0 && madre != 0) {
            em.createNativeQuery("INSERT INTO Referenze ( cellulare, email, id_capovillaggio, id_medico, id_paz, id_madre ) "
                    + "VALUES (?,?,?,?,?,?)").setParameter(1, cellulare).setParameter(2, email).setParameter(3, id_capovillaggio).setParameter(4, medico).setParameter(5, id_paziente).setParameter(6, madre).executeUpdate();
        } else {
            em.createNativeQuery("INSERT INTO Referenze ( cellulare, email, id_capovillaggio, id_medico, id_paz, id_madre, id_padre ) "
                    + "VALUES (?,?,?,?,?,?,?)").setParameter(1, cellulare).setParameter(2, email).setParameter(3, id_capovillaggio).setParameter(4, medico).setParameter(5, id_paziente).setParameter(6, madre).setParameter(7, padre).executeUpdate();

        }
        em.getTransaction().commit();




        return "success";
    }
}
